/********************************************************************
	created:	2012/02/22
	created:	22:2:2012   21:55
	file base:	Terrain
	file ext:	h
	author:		Baesky
	
	purpose:	The implementation of Terrain classes
*********************************************************************/

#pragma once
#include <iostream>
#include <fstream>
#include "ITerrain.h"

//class which inherit this are not be inherited by others
template <typename T>
class FinalClass
{
	friend T;
private:
	FinalClass();
	~FinalClass();
};

template <typename T>
FinalClass<T>::~FinalClass()
{

}

template <typename T>
FinalClass<T>::FinalClass()
{

}

//this class load terrain data from disk or other source.
class CHeightMapTerrain : public ITerrain,virtual public FinalClass<CHeightMapTerrain>
{
public:
	CHeightMapTerrain();
	~CHeightMapTerrain();
	//interface
	virtual bool InitTerrainData(const char* fileName, int terrainSize);					
	virtual bool ClearTerrainData();					
	virtual bool SaveTex(const char* fileName);							
	virtual bool SaveData(const char* fileName);								
	virtual void SetHeight(int x, int z, float val);
	virtual float GetRawHeight(int x, int z);	
	virtual float GetScaleHeight(int x, int z);

protected:
	struct SHeight_Data 
	{
		unsigned char* ucData;	//height data
		int iSize;				//size (power of 2)

		SHeight_Data()
		{
			ucData = NULL;
			iSize = 0;
		}
	};

private:
	SHeight_Data m_heightData;
	int m_iSize;
};

class CFaultInfomationTerrain:public ITerrain,virtual public FinalClass<CFaultInfomationTerrain>
{
public:
	CFaultInfomationTerrain();
	~CFaultInfomationTerrain();

	//interface
	virtual bool InitTerrainData(const char* fileName, int terrainSize);					
	virtual bool ClearTerrainData();					
	virtual bool SaveTex(const char* fileName);							
	virtual bool SaveData(const char* fileName);								
	virtual void SetHeight(int x, int z, float val);
	virtual float GetRawHeight(int x, int z);	
	virtual float GetScaleHeight(int x, int z);

private:
	//help func for FilterTerrain()
	void FilterTerrainBand(float* startBuff, int stride, int count,float erosion);
	//erosion the sharp eage of terrain
    void FilterTerrain(float eroVal);
	//generate height data
	void FaultInfoTerrain(int iterNums);

	//generate procedural texture
	//
	virtual float InterpolateHeight(int ix, int iz, float fH2tRadio);
	

private:
	float* m_fTerrainBuff;
};

//class CFaultInfoTerrain
//{
//public:
//	CFaultInfoTerrain();
//	~CFaultInfoTerrain();
//
//	void FaultInfoTerrain(int iterTime);
//
//	bool LoadHeightMap(unsigned seeds, int iSize);
//	bool UnloadHeightMap(void);
//	inline void SetHeightScale(float fScale)
//	{
//		m_fHeightScale = fScale;
//	}
//
//	inline float GetTrueHeightAtPoint(int iX, int iZ)
//	{
//		return fTerrainBuff[(iZ*m_iSize) + iX];
//	}
//
//	inline float GetScaledHeightAtPoint(int iX, int iZ)
//	{
//		return fTerrainBuff[(iZ*m_iSize) + iX]*m_fHeightScale;
//	}
//
//	void FilterHeightBand(int stride, int iCount, float fFilter);
//
//	float InterpolateHeight(int x, int y);
//
//	int m_iSize;
//	float* fTerrainBuff;
//	float  m_fHeightScale;
//};


//Mid-point Algorithm have some issue, delay to implement >_<
//class CMidPointTerrain
//{
//public:
//	CMidPointTerrain();
//	~CMidPointTerrain();
//
//	bool LoadHeightMap( unsigned seeds, int iSize);
//	inline void SetHeightScale(float fScale)
//	{
//		m_fHeightScale = fScale;
//	}
//
//	inline float GetTrueHeightAtPoint(int iX, int iZ)
//	{
//		return fTerrainBuff[(iZ*m_iSize) + iX];
//	}
//
//	inline float GetScaledHeightAtPoint(int iX, int iZ)
//	{
//		return fTerrainBuff[(iZ*m_iSize) + iX]*m_fHeightScale;
//	}
//
//	void MidPointSetup(int left, int top, int width, int height, float fDeltaH,float fRoughness);
//	void CalcSquareStep(int left, int top, int width, int height, float fDeltaH);
//
//	int m_iSize;
//	float* fTerrainBuff;
//	float  m_fHeightScale;
//};